서버 캐시 (Server Cache)
서버 캐시는 자주 요청되는 데이터나 계산 비용이 높은 결과물을 고속 접근이 가능한 임시 저장소에 보관하여, 동일한 요청 시 원본 데이터 소스(DB, API 등)에 접근하지 않고 빠르게 응답을 제공하는 기술이다.
목차
- 개요
- 캐시 계층 구조 (Caching Layers)
- 로컬 캐시 vs 글로벌 캐시
- 캐시 전략 및 알고리즘
- 캐시 히트율 및 측정 지표
- 캐시 일관성 및 무효화 (Cache Invalidation)
- 주요 구현 기술 및 도구
- 성능 최적화 시 주의사항 및 해결 방안
- 실제 서비스 적용 사례 (Use Case)
1. 개요
서버 캐시의 핵심 목적은 응답 속도(Latency) 향상과 백엔드 시스템의 부하 감소에 있다. 데이터베이스(DB)나 외부 API 호출은 디스크 I/O나 네트워크 통신을 수반하므로 상대적으로 느리다. 반면, 캐시는 주로 RAM(Random Access Memory)과 같은 인메모리(In-memory) 저장소를 사용하므로 데이터 읽기 속도가 비약적으로 빠르다.
기본 작동 원리:
1. 요청이 들어오면 먼저 캐시 저장소에 해당 데이터가 있는지 확인한다.
2. 데이터가 존재하면 즉시 반환한다. (캐시 히트, Cache Hit)
3. 데이터가 없으면 원본 소스에서 데이터를 가져와 캐시에 저장한 후 반환한다. (캐시 미스, Cache Miss)
2. 캐시 계층 구조 (Caching Layers)
현대적인 웹 아키텍처에서는 단일 캐시가 아닌, 요청 경로에 따라 다층적인 캐시 구조를 설계하여 효율을 극대화한다.
| 계층 |
위치 |
저장 대상 |
주요 도구/기술 |
특성 |
| 클라이언트 |
브라우저/앱 |
정적 리소스, API 응답 |
HTTP Cache, Service Worker |
사용자 기기에 저장, 네트워크 비용 제로 |
| CDN |
엣지 서버 |
이미지, JS, CSS, HTML |
Cloudflare, Akamai, AWS CloudFront |
지리적으로 분산된 서버, 물리적 거리 단축 |
| 웹 서버 |
리버스 프록시 |
렌더링된 페이지, 정적 파일 |
Nginx, Varnish |
애플리케이션 서버 진입 전 필터링 |
| 애플리케이션 |
서버 메모리 |
세션, 설정 값, 빈번한 쿼리 |
Local Cache (Ehcache, Caffeine) |
프로세스 내부 접근, 가장 빠른 속도 |
| 분산 캐시 |
별도 캐시 서버 |
공유 데이터, 세션, 랭킹 |
Redis, Memcached |
여러 서버가 공유, 데이터 일관성 유지 |
3. 로컬 캐시 vs 글로벌 캐시
캐시의 저장 위치와 공유 범위에 따라 로컬 캐시와 글로벌(분산) 캐시로 구분한다.
| 구분 |
로컬 캐시 (Local Cache) |
글로벌 캐시 (Global/Distributed Cache) |
| 저장 위치 |
개별 애플리케이션 서버의 메모리 |
별도의 독립된 캐시 서버 클러스터 |
| 접근 속도 |
매우 빠름 (네트워크 통신 없음) |
빠름 (네트워크 통신 필요) |
| 데이터 일관성 |
서버마다 데이터가 달라 불일치 발생 가능 |
모든 서버가 동일한 데이터를 참조하여 일관됨 |
| 확장성 |
서버 증설 시 메모리 낭비 발생 |
독립적 확장 가능, 대용량 데이터 저장 유리 |
| 적합한 사례 |
변경 빈도가 매우 낮은 설정 값, 정적 데이터 |
세션 정보, 실시간 랭킹, 공유 상태 값 |
4. 캐시 전략 및 알고리즘
4.1 읽기/쓰기 전략
데이터를 언제 캐시에 쓰고 읽을 것인지에 따라 시스템의 일관성과 성능이 결정된다.
- Look-aside (Cache-Aside): 가장 일반적인 패턴. 애플리케이션이 먼저 캐시를 확인하고, 없으면 DB에서 가져와 캐시에 저장한다. 캐시에 이미 저장된 데이터에 한해 DB 장애 시에도 응답이 가능하지만, 첫 요청은 항상 느리다.
- Read-through: 캐시가 데이터 소스 역할을 한다. 애플리케이션은 캐시에만 요청하고, 캐시가 내부적으로 DB에서 데이터를 가져와 업데이트한다.
- Write-through: 데이터를 쓸 때 캐시와 DB에 동시에 저장한다. 데이터 일관성이 매우 높지만, 쓰기 성능이 저하된다.
- Write-around: 데이터를 DB에만 저장하고 캐시는 업데이트하지 않거나 무효화한다. 쓰기 성능이 좋고 캐시 오염을 방지할 수 있으나, 이후 첫 읽기 요청 시 캐시 미스가 발생한다.
- Write-back (Write-behind): 데이터를 캐시에만 먼저 저장하고, 일정 주기나 조건에 따라 DB에 일괄 반영한다. 쓰기 성능이 극대화되나, 캐시 서버 장애 시 데이터 유실 위험이 있다.
[읽기/쓰기 전략 비교]
| 전략 |
읽기 성능 |
쓰기 성능 |
일관성 |
특징 |
| Look-aside |
높음 |
높음 |
보통 |
가장 범용적, 캐시 미스 시 DB 부하 |
| Read-through |
높음 |
보통 |
높음 |
애플리케이션 로직 단순화 |
| Write-through |
높음 |
낮음 |
매우 높음 |
데이터 유실 위험 없음, 쓰기 지연 발생 |
| Write-around |
보통 |
높음 |
보통 |
캐시 오염 방지, 첫 읽기 속도 저하 |
| Write-back |
매우 높음 |
매우 높음 |
낮음 |
쓰기 최적화, 데이터 유실 가능성 존재 |
4.2 메모리 관리 알고리즘 (Eviction Policy)
캐시 공간이 가득 찼을 때 어떤 데이터를 삭제할지 결정하는 알고리즘이다.
- LRU (Least Recently Used): 가장 오랫동안 참조되지 않은 데이터를 삭제한다. 최근 사용 경향을 반영하므로 가장 널리 쓰인다.
- LFU (Least Frequently Used): 참조 횟수가 가장 적은 데이터를 삭제한다. 빈도수를 기준으로 하며, 갑자기 많이 쓰이다가 안 쓰이는 데이터 처리에 취약할 수 있다.
- FIFO (First In First Out): 가장 먼저 들어온 데이터를 먼저 삭제한다.
캐시의 효율성을 측정하기 위해 히트율(Hit Rate)을 모니터링하는 것이 필수적이다.
캐시 히트율 계산식:
$$\text{Cache Hit Rate} = \frac{\text{Cache Hits}}{\text{Cache Hits} + \text{Cache Misses}} \times 100 (\%)$$
주요 측정 지표:
* Hit Rate: 전체 요청 중 캐시에서 응답한 비율. 높을수록 DB 부하가 적다.
* Miss Rate: 캐시에 데이터가 없어 원본 소스에 접근한 비율 ($1 - \text{Hit Rate}$).
* Latency: 캐시 히트 시의 응답 시간과 미스 시의 응답 시간 차이를 측정하여 성능 개선 폭을 확인한다.
6. 캐시 일관성 및 무효화 (Cache Invalidation)
캐시의 가장 어려운 과제는 원본 데이터가 변경되었을 때 캐시된 데이터를 어떻게 처리하느냐 하는 캐시 일관성(Cache Consistency) 문제이다.
- TTL (Time To Live): 데이터에 유효 기간을 설정하여 시간이 지나면 자동으로 삭제되게 하는 방법이다. 일관성을 완벽히 보장하지는 않지만, 구현이 간단하고 메모리 관리가 효율적이다.
- Explicit Invalidation (강제 무효화): 원본 데이터가 수정/삭제될 때, 애플리케이션이 관련 캐시 키를 명시적으로 삭제(Evict)하는 방식이다. 데이터 변경 즉시 반영이 가능하여 일관성이 높다.
- Write-through/Write-back: 쓰기 전략 단계에서 캐시와 DB를 동시에 업데이트하거나 순차적으로 반영하여 일관성을 유지한다.
- Version-based Invalidation: 데이터에 버전 번호를 부여하고, 버전이 변경되면 이전 캐시 데이터를 무효화하는 방식이다.
7. 주요 구현 기술 및 도구
가장 대표적인 인메모리 저장소인 Redis와 Memcached의 비교 분석이다.
| 비교 항목 |
Redis |
Memcached |
| 데이터 구조 |
String, List, Set, Sorted Set, Hash 등 다양함 |
단순 Key-Value (String) |
| 영속성 |
스냅샷(RDB), 로그(AOF)를 통해 디스크 저장 가능 |
지원하지 않음 (휘발성) |
| 복제 및 고가용성 |
Redis Sentinel, Cluster를 통한 고가용성 지원 |
기본적으로 지원하지 않음 (클라이언트 단 처리) |
| 멀티 스레드 |
명령어 실행은 싱글 스레드, 네트워크 I/O는 멀티 스레드 지원(v6.0+) |
멀티 스레드 기반 |
| 주요 용도 |
캐시, 메시지 브로커, 데이터베이스, 랭킹 시스템 |
단순하고 빠른 캐싱 전용 |
8. 성능 최적화 시 주의사항 및 해결 방안
캐시 도입 시 발생할 수 있는 특수한 장애 상황과 대응책이다. 캐시 스탬피드는 단일 핫 키(Hot Key)의 만료에, 캐시 눈사태는 다수 키의 동시 만료에 초점이 맞춰져 있다는 점이 핵심적인 차이이다.
- 캐시 펜트레이션 (Cache Penetration): 존재하지 않는 데이터에 대해 지속적으로 요청이 들어와 모든 요청이 DB로 전달되는 현상이다.
- 해결책: 존재하지 않는 값도 짧은 TTL로 캐싱하거나, 블룸 필터(Bloom Filter)를 사용하여 존재 여부를 먼저 확인한다.
- 캐시 스탬피드 (Cache Stampede): 대규모 트래픽 상황에서 특정 인기 데이터(Hot Key)의 캐시가 만료되는 순간, 수많은 요청이 동시에 DB로 몰려 시스템이 마비되는 현상이다.
- 해결책: TTL에 무작위 시간(Jitter)을 추가하여 만료 시점을 분산시키거나, 뮤텍스(Mutex) 락을 사용하여 단 하나의 요청만 DB에서 데이터를 갱신하게 하고 나머지 요청은 대기하거나 이전 데이터를 사용하게 한다.
- 캐시 눈사태 (Cache Avalanche): 많은 양의 캐시 키가 동시에 만료되어 DB에 과부하가 걸리는 현상이다.
- 해결책: TTL 분산 설정 및 회로 차단기(Circuit Breaker) 도입.
9. 실제 서비스 적용 사례 (Use Case)
- 전자상거래 상품 상세 페이지:
- 상품 정보는 변경 빈도가 낮지만 조회수가 매우 높다. 상품 정보를 Redis에 캐싱하여 DB 조회를 최소화하고 페이지 로딩 속도를 개선한다.
- 실시간 랭킹 시스템 (게임/차트):
- 수만 명의 점수를 실시간으로 정렬하여 보여줘야 할 때, DB의
ORDER BY 쿼리는 매우 느리다. Redis의 Sorted Set 자료구조를 사용하여 메모리 상에서 실시간 정렬 및 랭킹을 구현한다.
- 사용자 세션 관리:
- 분산 서버 환경에서 사용자의 로그인 상태를 유지하기 위해 세션 정보를 글로벌 캐시에 저장한다. 이를 통해 사용자가 어떤 서버로 접속하더라도 동일한 로그인 상태를 유지(Session Clustering)할 수 있다.
- API 응답 캐싱:
- 외부 날씨 API나 환율 API처럼 호출 비용이 발생하거나 업데이트 주기가 정해진 데이터의 경우, 일정 시간(예: 1시간) 동안 응답 값을 캐싱하여 API 호출 비용을 절감하고 응답 속도를 높인다.
# 서버 캐시 (Server Cache)
서버 캐시는 자주 요청되는 데이터나 계산 비용이 높은 결과물을 고속 접근이 가능한 임시 저장소에 보관하여, 동일한 요청 시 원본 데이터 소스(DB, API 등)에 접근하지 않고 빠르게 응답을 제공하는 기술이다.
## 목차
1. [개요](#1-개요)
2. [캐시 계층 구조 (Caching Layers)](#2-캐시-계층-구조-caching-layers)
3. [로컬 캐시 vs 글로벌 캐시](#3-로컬-캐시-vs-글로벌-캐시)
4. [캐시 전략 및 알고리즘](#4-캐시-전략-및-알고리즘)
5. [캐시 히트율 및 측정 지표](#5-캐시-히트율-및-측정-지표)
6. [캐시 일관성 및 무효화 (Cache Invalidation)](#6-캐시-일관성-및-무효화-cache-invalidation)
7. [주요 구현 기술 및 도구](#7-주요-구현-기술-및-도구)
8. [성능 최적화 시 주의사항 및 해결 방안](#8-성능-최적화-시-주의사항-및-해결-방안)
9. [실제 서비스 적용 사례 (Use Case)](#9-실제-서비스-적용-사례-use-case)
## 1. 개요
서버 캐시의 핵심 목적은 **응답 속도(Latency) 향상**과 **백엔드 시스템의 부하 감소**에 있다. 데이터베이스(DB)나 외부 API 호출은 디스크 I/O나 네트워크 통신을 수반하므로 상대적으로 느리다. 반면, 캐시는 주로 RAM(Random Access Memory)과 같은 인메모리(In-memory) 저장소를 사용하므로 데이터 읽기 속도가 비약적으로 빠르다.
**기본 작동 원리:**
1. 요청이 들어오면 먼저 캐시 저장소에 해당 데이터가 있는지 확인한다.
2. 데이터가 존재하면 즉시 반환한다. (**캐시 히트, Cache Hit**)
3. 데이터가 없으면 원본 소스에서 데이터를 가져와 캐시에 저장한 후 반환한다. (**캐시 미스, Cache Miss**)
## 2. 캐시 계층 구조 (Caching Layers)
현대적인 웹 아키텍처에서는 단일 캐시가 아닌, 요청 경로에 따라 다층적인 캐시 구조를 설계하여 효율을 극대화한다.
| 계층 | 위치 | 저장 대상 | 주요 도구/기술 | 특성 |
| :--- | :--- | :--- | :--- | :--- |
| **클라이언트** | 브라우저/앱 | 정적 리소스, API 응답 | HTTP Cache, Service Worker | 사용자 기기에 저장, 네트워크 비용 제로 |
| **CDN** | 엣지 서버 | 이미지, JS, CSS, HTML | Cloudflare, Akamai, AWS CloudFront | 지리적으로 분산된 서버, 물리적 거리 단축 |
| **웹 서버** | 리버스 프록시 | 렌더링된 페이지, 정적 파일 | Nginx, Varnish | 애플리케이션 서버 진입 전 필터링 |
| **애플리케이션** | 서버 메모리 | 세션, 설정 값, 빈번한 쿼리 | Local Cache (Ehcache, Caffeine) | 프로세스 내부 접근, 가장 빠른 속도 |
| **분산 캐시** | 별도 캐시 서버 | 공유 데이터, 세션, 랭킹 | Redis, Memcached | 여러 서버가 공유, 데이터 일관성 유지 |
## 3. 로컬 캐시 vs 글로벌 캐시
캐시의 저장 위치와 공유 범위에 따라 로컬 캐시와 글로벌(분산) 캐시로 구분한다.
| 구분 | 로컬 캐시 (Local Cache) | 글로벌 캐시 (Global/Distributed Cache) |
| :--- | :--- | :--- |
| **저장 위치** | 개별 애플리케이션 서버의 메모리 | 별도의 독립된 캐시 서버 클러스터 |
| **접근 속도** | 매우 빠름 (네트워크 통신 없음) | 빠름 (네트워크 통신 필요) |
| **데이터 일관성** | 서버마다 데이터가 달라 불일치 발생 가능 | 모든 서버가 동일한 데이터를 참조하여 일관됨 |
| **확장성** | 서버 증설 시 메모리 낭비 발생 | 독립적 확장 가능, 대용량 데이터 저장 유리 |
| **적합한 사례** | 변경 빈도가 매우 낮은 설정 값, 정적 데이터 | 세션 정보, 실시간 랭킹, 공유 상태 값 |
## 4. 캐시 전략 및 알고리즘
### 4.1 읽기/쓰기 전략
데이터를 언제 캐시에 쓰고 읽을 것인지에 따라 시스템의 일관성과 성능이 결정된다.
* **Look-aside (Cache-Aside):** 가장 일반적인 패턴. 애플리케이션이 먼저 캐시를 확인하고, 없으면 DB에서 가져와 캐시에 저장한다. 캐시에 이미 저장된 데이터에 한해 DB 장애 시에도 응답이 가능하지만, 첫 요청은 항상 느리다.
* **Read-through:** 캐시가 데이터 소스 역할을 한다. 애플리케이션은 캐시에만 요청하고, 캐시가 내부적으로 DB에서 데이터를 가져와 업데이트한다.
* **Write-through:** 데이터를 쓸 때 캐시와 DB에 동시에 저장한다. 데이터 일관성이 매우 높지만, 쓰기 성능이 저하된다.
* **Write-around:** 데이터를 DB에만 저장하고 캐시는 업데이트하지 않거나 무효화한다. 쓰기 성능이 좋고 캐시 오염을 방지할 수 있으나, 이후 첫 읽기 요청 시 캐시 미스가 발생한다.
* **Write-back (Write-behind):** 데이터를 캐시에만 먼저 저장하고, 일정 주기나 조건에 따라 DB에 일괄 반영한다. 쓰기 성능이 극대화되나, 캐시 서버 장애 시 데이터 유실 위험이 있다.
**[읽기/쓰기 전략 비교]**
| 전략 | 읽기 성능 | 쓰기 성능 | 일관성 | 특징 |
| :--- | :--- | :--- | :--- | :--- |
| **Look-aside** | 높음 | 높음 | 보통 | 가장 범용적, 캐시 미스 시 DB 부하 |
| **Read-through** | 높음 | 보통 | 높음 | 애플리케이션 로직 단순화 |
| **Write-through** | 높음 | 낮음 | 매우 높음 | 데이터 유실 위험 없음, 쓰기 지연 발생 |
| **Write-around** | 보통 | 높음 | 보통 | 캐시 오염 방지, 첫 읽기 속도 저하 |
| **Write-back** | 매우 높음 | 매우 높음 | 낮음 | 쓰기 최적화, 데이터 유실 가능성 존재 |
### 4.2 메모리 관리 알고리즘 (Eviction Policy)
캐시 공간이 가득 찼을 때 어떤 데이터를 삭제할지 결정하는 알고리즘이다.
* **LRU (Least Recently Used):** 가장 오랫동안 참조되지 않은 데이터를 삭제한다. 최근 사용 경향을 반영하므로 가장 널리 쓰인다.
* **LFU (Least Frequently Used):** 참조 횟수가 가장 적은 데이터를 삭제한다. 빈도수를 기준으로 하며, 갑자기 많이 쓰이다가 안 쓰이는 데이터 처리에 취약할 수 있다.
* **FIFO (First In First Out):** 가장 먼저 들어온 데이터를 먼저 삭제한다.
## 5. 캐시 히트율 및 측정 지표
캐시의 효율성을 측정하기 위해 히트율(Hit Rate)을 모니터링하는 것이 필수적이다.
**캐시 히트율 계산식:**
$$\text{Cache Hit Rate} = \frac{\text{Cache Hits}}{\text{Cache Hits} + \text{Cache Misses}} \times 100 (\%)$$
**주요 측정 지표:**
* **Hit Rate:** 전체 요청 중 캐시에서 응답한 비율. 높을수록 DB 부하가 적다.
* **Miss Rate:** 캐시에 데이터가 없어 원본 소스에 접근한 비율 ($1 - \text{Hit Rate}$).
* **Latency:** 캐시 히트 시의 응답 시간과 미스 시의 응답 시간 차이를 측정하여 성능 개선 폭을 확인한다.
## 6. 캐시 일관성 및 무효화 (Cache Invalidation)
캐시의 가장 어려운 과제는 원본 데이터가 변경되었을 때 캐시된 데이터를 어떻게 처리하느냐 하는 **캐시 일관성(Cache Consistency)** 문제이다.
* **TTL (Time To Live):** 데이터에 유효 기간을 설정하여 시간이 지나면 자동으로 삭제되게 하는 방법이다. 일관성을 완벽히 보장하지는 않지만, 구현이 간단하고 메모리 관리가 효율적이다.
* **Explicit Invalidation (강제 무효화):** 원본 데이터가 수정/삭제될 때, 애플리케이션이 관련 캐시 키를 명시적으로 삭제(Evict)하는 방식이다. 데이터 변경 즉시 반영이 가능하여 일관성이 높다.
* **Write-through/Write-back:** 쓰기 전략 단계에서 캐시와 DB를 동시에 업데이트하거나 순차적으로 반영하여 일관성을 유지한다.
* **Version-based Invalidation:** 데이터에 버전 번호를 부여하고, 버전이 변경되면 이전 캐시 데이터를 무효화하는 방식이다.
## 7. 주요 구현 기술 및 도구
가장 대표적인 인메모리 저장소인 Redis와 Memcached의 비교 분석이다.
| 비교 항목 | Redis | Memcached |
| :--- | :--- | :--- |
| **데이터 구조** | String, List, Set, Sorted Set, Hash 등 다양함 | 단순 Key-Value (String) |
| **영속성** | 스냅샷(RDB), 로그(AOF)를 통해 디스크 저장 가능 | 지원하지 않음 (휘발성) |
| **복제 및 고가용성** | Redis Sentinel, Cluster를 통한 고가용성 지원 | 기본적으로 지원하지 않음 (클라이언트 단 처리) |
| **멀티 스레드** | 명령어 실행은 싱글 스레드, 네트워크 I/O는 멀티 스레드 지원(v6.0+) | 멀티 스레드 기반 |
| **주요 용도** | 캐시, 메시지 브로커, 데이터베이스, 랭킹 시스템 | 단순하고 빠른 캐싱 전용 |
## 8. 성능 최적화 시 주의사항 및 해결 방안
캐시 도입 시 발생할 수 있는 특수한 장애 상황과 대응책이다. **캐시 스탬피드는 단일 핫 키(Hot Key)의 만료에, 캐시 눈사태는 다수 키의 동시 만료에 초점이 맞춰져 있다는 점이 핵심적인 차이이다.**
* **캐시 펜트레이션 (Cache Penetration):** 존재하지 않는 데이터에 대해 지속적으로 요청이 들어와 모든 요청이 DB로 전달되는 현상이다.
* *해결책:* 존재하지 않는 값도 짧은 TTL로 캐싱하거나, **블룸 필터(Bloom Filter)**를 사용하여 존재 여부를 먼저 확인한다.
* **캐시 스탬피드 (Cache Stampede):** 대규모 트래픽 상황에서 특정 인기 데이터(Hot Key)의 캐시가 만료되는 순간, 수많은 요청이 동시에 DB로 몰려 시스템이 마비되는 현상이다.
* *해결책:* TTL에 무작위 시간(Jitter)을 추가하여 만료 시점을 분산시키거나, 뮤텍스(Mutex) 락을 사용하여 단 하나의 요청만 DB에서 데이터를 갱신하게 하고 나머지 요청은 대기하거나 이전 데이터를 사용하게 한다.
* **캐시 눈사태 (Cache Avalanche):** 많은 양의 캐시 키가 동시에 만료되어 DB에 과부하가 걸리는 현상이다.
* *해결책:* TTL 분산 설정 및 회로 차단기(Circuit Breaker) 도입.
## 9. 실제 서비스 적용 사례 (Use Case)
1. **전자상거래 상품 상세 페이지:**
* 상품 정보는 변경 빈도가 낮지만 조회수가 매우 높다. 상품 정보를 Redis에 캐싱하여 DB 조회를 최소화하고 페이지 로딩 속도를 개선한다.
2. **실시간 랭킹 시스템 (게임/차트):**
* 수만 명의 점수를 실시간으로 정렬하여 보여줘야 할 때, DB의 `ORDER BY` 쿼리는 매우 느리다. Redis의 `Sorted Set` 자료구조를 사용하여 메모리 상에서 실시간 정렬 및 랭킹을 구현한다.
3. **사용자 세션 관리:**
* 분산 서버 환경에서 사용자의 로그인 상태를 유지하기 위해 세션 정보를 글로벌 캐시에 저장한다. 이를 통해 사용자가 어떤 서버로 접속하더라도 동일한 로그인 상태를 유지(Session Clustering)할 수 있다.
4. **API 응답 캐싱:**
* 외부 날씨 API나 환율 API처럼 호출 비용이 발생하거나 업데이트 주기가 정해진 데이터의 경우, 일정 시간(예: 1시간) 동안 응답 값을 캐싱하여 API 호출 비용을 절감하고 응답 속도를 높인다.